package com.toubutu.audio.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.toubutu.audio.admin.dto.RoleDto;
import com.toubutu.audio.admin.dto.RolePermissionBindDto;
import com.toubutu.audio.admin.dto.UserRoleBindDto;
import com.toubutu.audio.admin.entity.Role;
import com.toubutu.audio.admin.mapper.RoleMapper;
import com.toubutu.audio.admin.mapper.UserRoleMapper;
import com.toubutu.audio.admin.service.RolePermissionService;
import com.toubutu.audio.admin.service.RoleService;
import com.toubutu.audio.admin.vo.RoleVo;
import com.toubutu.common.BusinessException;
import com.toubutu.common.PageUtils;
import com.toubutu.common.StatusCodeEnum;
import com.toubutu.constants.BaseConstants;

import com.toubutu.util.RedisService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 戒燥
 * @since 2023-09-30
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Resource
    private RolePermissionService rolePermissionService;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private RedisService redisService;

    private static final String AUTH_USER_INFO_KEY= "authUserInfo:";

    @Override
    public List<RoleVo> getAllRoles() {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getIsDelete,BaseConstants.UN_DELETED);
        List<Role> roles = list(queryWrapper);
        if (roles.isEmpty()){
            return Collections.emptyList();
        }
       return roles.stream().map(r->{
           RoleVo roleVo = new RoleVo();
           BeanUtils.copyProperties(r,roleVo);
           return roleVo;
       }).collect(Collectors.toList());
    }

    @Override
    public PageUtils<RoleVo> getRolePageList(Long size, Long page) {
        Page<Role> rolePage = new Page<>(page,size);
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getIsDelete, BaseConstants.UN_DELETED);
        rolePage = this.page(rolePage, wrapper);
        List<RoleVo> collect = rolePage.getRecords().stream().map(role -> {
            RoleVo roleVo = new RoleVo();
            BeanUtils.copyProperties(role, roleVo);
            return roleVo;
        }).collect(Collectors.toList());
        return new PageUtils<>(collect,rolePage);
    }

    @Override
    @Transactional
    public Boolean deleteRoleById(Integer roleId) {
        Boolean flag = false;
        RoleServiceImpl roleService = (RoleServiceImpl) AopContext.currentProxy();
        LambdaUpdateWrapper<Role> roleWrapper = new LambdaUpdateWrapper<>();
        roleWrapper.eq(Role::getRoleId,roleId);
        roleWrapper.set(Role::getIsDelete,BaseConstants.DELETED);
        flag = roleService.update(roleWrapper);
        //删除role-menu关联表数据
        flag = rolePermissionService.deleteRolePermissionByRoleId(roleId);
        //TODO 删除 user-role数据
        return flag;
    }

    @Override
    public Boolean updateRole(RoleDto roleDto) {
        return this.saveOrUpdate(roleDto.toPo());
    }

    @Override
    public Boolean saveRole(RoleDto role) {
        //根据角色名称，标识查询
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleName,role.getRoleName());
        wrapper.eq(Role::getIsDelete,BaseConstants.UN_DELETED);
        Role one = this.getOne(wrapper);
        if (one!=null){
            throw new BusinessException(StatusCodeEnum.USER_HANDLE.getCode(),"角色名称重复");
        }
        wrapper.clear();
        wrapper.eq(Role::getRoleTag,role.getRoleTag());
        wrapper.eq(Role::getIsDelete,BaseConstants.UN_DELETED);
        one = this.getOne(wrapper);
        if (one!=null){
            throw new BusinessException(StatusCodeEnum.USER_HANDLE.getCode(),"角色名称重复");
        }
        return this.save(role.toPo());
    }

    @Override
    public Boolean bindRoleToUser(UserRoleBindDto userRoleBindDto) {
        //先删除原有关系
        userRoleMapper.deleteByUserId(userRoleBindDto.getUserId());
        //再绑定关系
        if (!userRoleBindDto.getRoleIds().isEmpty()){
          userRoleBindDto.setRoleIds(userRoleBindDto.getRoleIds().stream().distinct().collect(Collectors.toList()));
            userRoleMapper.bindUserRole(userRoleBindDto);
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean bindRoleToPermission(RolePermissionBindDto rolePermissionBindDto) {
        //1.先删除原来的绑定关系
        rolePermissionService.deleteRolePermissionByRoleId(rolePermissionBindDto.getRoleId());
        //2.再进行批量插入
        rolePermissionService.saveBatch(rolePermissionBindDto);

        return true;
    }

    @Override
    public List<Integer> getBindPermissionIdsByRoleId(Integer roleId) {
        return rolePermissionService.getPermissionIdsByRoleId(roleId);
    }

    @Override
    public RoleVo getRoleInfoById(Integer roleId) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleId,roleId).eq(Role::getIsDelete,BaseConstants.UN_DELETED);
        Role role = this.getOne(wrapper);
        if (role==null){
            throw new BusinessException(StatusCodeEnum.NOT_FOUND.getCode(),"角色信息不存在");
        }
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(role,roleVo);
        return roleVo;
    }

    @Override
    public void enableRole(Integer roleId, Integer isEnable) {
        LambdaUpdateWrapper<Role> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Role::getRoleId,roleId);
        wrapper.set(Role::getIsEnable,isEnable);
        this.update(wrapper);
    }

    @Override
    public Map<Integer, String> getRoleNameByRoleIds(List<Integer> roleIds) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Role::getRoleId,roleIds);
        return list(wrapper).stream().collect(Collectors.toMap(Role::getRoleId, Role::getRoleName));
    }

    @Override
    public List<RoleVo> getUserRoles(Long userId) {
        return userRoleMapper.getUserRoleList(userId);
    }

    @Override
    public List<String> getPermissionCodeByRoleIds(List<Integer> roleIds) {
        return rolePermissionService.getPermissionCodeByRoleList(roleIds);
    }
}
